# -*- coding: utf-8 -*-
import datetime
import logging
import re

from django.http import JsonResponse
from rest_framework import status
from rest_framework.views import APIView

from DataBase.DatabaseConsts import StockAnnounceDB, LiduoLikongForCodeTablePrefix, FinancialDB
from Utils.Funcc import parse_rp_2_dicts, parse_date_from_s
from WebServer.blog.Utils.Fnc import paginator_sql, generate_mutil_or_like, generate_message_dict_4_fail, \
    wrapper_res_dict
from WebServer.blog.models import HDY_DBSession_mysql
log = logging.getLogger(__name__)


def wrapper_2_list(kws):
    if not type(kws) == list:
        kws = [kws, ]
    return kws

class HuDongYiQuestionApiView(APIView):
    def post(self, request):
        # #print("input : {}".format(request.data))
        kws = wrapper_2_list(request.data.get("kw", []))

        session = HDY_DBSession_mysql()
        res = {}
        try:
            if kws:
                all_kws_res = []
                # data = session.query(HuDongYiQuestion).filter(HuDongYiQuestion.code.like("%{}%".format(kw))).all()
                paginator = paginator_sql(request.data.get("cur_page", None), request.data.get("page_size", None))

                # for kw_ in kws:
                # reg = generate_mutil_or_reg(kws)
                # #print("reg :" + reg)
                like = " HDYQ.code = '{}' ".format(kws[0])
                sql = "SELECT HDYQ.* FROM hudongyiquestion AS HDYQ WHERE  {}  ORDER BY HDYQ.time DESC ".format(like) + paginator['sql']
                #print("sql:"+sql)
                rp = session.execute(sql
                                     )
                tmp_data = parse_rp_2_dicts(rp)
                all_kws_res = tmp_data
                    # append_distinct_2_res(tmp_data, all_kws_res)
                res['data'] = all_kws_res
                # res['data'] = all_kws_res[ :paginator['size']]
                # res['data'] = parse_sqlalchemy_model_2_dict(data)
        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()

class HuDongYiQuestionAllApiView(APIView):
    def post(self, request):
        # #print("input : {}".format(request.data))
        kws = wrapper_2_list(request.data.get("kw", []))
        only_today = request.data.get("only_today",False)
        if only_today:
            today_str = datetime.datetime.today().strftime("%Y-%m-%d")
        # 去除ST
        session = HDY_DBSession_mysql()
        res = {}
        try:
            if kws:
                paginator = paginator_sql(request.data.get("cur_page", None), request.data.get("page_size", None))
                like = generate_mutil_or_like("CONCAT(  HDYQ.question, HDYQ.answer)",kws)

                if only_today:
                    order_by_sql = " and time like '{}%' order by  code DESC,time DESC ".format(today_str)
                else:
                    order_by_sql = " order by time DESC "
                sql = "SELECT HDYQ.* FROM hudongyiquestion AS HDYQ WHERE  HDYQ.name NOT LIKE '%ST' AND {}   {} ".format(like, order_by_sql) + paginator['sql']
                ##print("sql:"+sql)
                rp = session.execute(sql
                                     )
                tmp_data = parse_rp_2_dicts(rp)
                all_kws_res = tmp_data
                    # append_distinct_2_res(tmp_data, all_kws_res)
                res['data'] = all_kws_res
                # res['data'] = all_kws_res[ :paginator['size']]
                # res['data'] = parse_sqlalchemy_model_2_dict(data)
        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()

class TaoGuBaPostApiView(APIView):
    def post(self, request):
        # ##print("input : {}".format(request.data))
        kws = request.data.get("kw", [])
        session = HDY_DBSession_mysql()
        res = {}
        try:
            if kws:
                paginator = paginator_sql(request.data.get("cur_page", None), request.data.get("page_size", None))
                like = generate_mutil_or_like("CONCAT(TGB.title)",kws)
                sql = "SELECT TGB.title, TGB.date,TGB.article_url,TGB.writer FROM forumposts.taogubaposts AS TGB WHERE {} ORDER BY TGB.date desc, TGB.approval desc ".format(like) + paginator['sql']
                rp = session.execute(sql)
                res['data'] = parse_rp_2_dicts(rp)

        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()


class StockTagApiView(APIView):
    def post(self, request):
        ##print("input : {}".format(request.data))
        kws = wrapper_2_list(request.data.get("kw", []))
        min_price = request.data.get("min_price")
        max_price = request.data.get("max_price")
        yearone = str(datetime.date.today().year - 1)+ "1231"
        yeartwo = str(datetime.date.today().year - 2) + "1231"

        # 需要区分kws中的code 和 other
        codes, others = [],[]
        for kw_ in kws:
            if re.match("\d{6}", kw_):
                codes.append(kw_)
            else:
                others.append(kw_)

        session = HDY_DBSession_mysql()
        res = {}
        try:
            paginator = paginator_sql(all = False if kws else True, **request.query_params)
            if kws:
                rp = []
                like_other_sql = generate_mutil_or_like(" CONCAT(ST.name, ST.tag) ", others)
                other_sql = ""
                if others:
                    other_sql = (" OR " if codes else " " )+" ( ({})".format(
                        like_other_sql) + "  AND ( ST.`name` NOT LIKE '%ST%' AND ST. CODE NOT IN ( ( SELECT CODE FROM financialreport.income WHERE date = :one_year AND n_income < 0 AND CODE IN ( SELECT CODE FROM financialreport.income WHERE date = :two_year and n_income < 0) UNION ALL SELECT CODE FROM financialreport.balancesheet WHERE date = :one_year AND CAST( goodwill / (total_assets - total_liab) AS DECIMAL (10, 2) ) > 0.20 ) ) ) )"
                sql = "SELECT ST.code , ST.name ,ST.tag from stocktag.stocktag as ST INNER JOIN stocktag.stock_daily as SD ON SD.code = ST.code " \
                      " WHERE SD.close>= :min_price AND SD.close <= :max_price  AND (  " + generate_mutil_or_like(
                    " CONCAT(ST.code) ", codes, need_where=False, wrapper=True) + other_sql + " ) ORDER BY CODE ASC " + \
                      paginator['sql']
                #print(sql)
                rp = session.execute(sql, {'one_date': yearone, 'two_date': yeartwo, 'min_price': min_price,
                                           "max_price": max_price,
                                           'one_year': yearone, 'two_year': yeartwo})

                res['data'] = parse_rp_2_dicts(rp)

        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()


class StockTagDetailApiView(APIView):
    def post(self, request):
        ##print("input : {}".format(request.data))
        kw = wrapper_2_list(request.data.get("kw", []))
        session = HDY_DBSession_mysql()
        res = {}
        try:
            if kw:
                paginator = paginator_sql(all = False if kw else True, **request.query_params)
                like_sql = generate_mutil_or_like("CONCAT(STR.code)", kw, need_where=True)
                rp = session.execute("SELECT STR.* FROM stocktag.stocktagrelation AS STR  " + like_sql  + " ORDER BY STR.CODE ASC " + paginator['sql'])
                res['data'] = parse_rp_2_dicts(rp)

        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()


def generate_mutil_case_sql(base_sql, duo_list):
    res = ""
    for do_  in duo_list:
        if do_.startswith("%") and do_.endswith("%"):
            do_ = do_[1:-1]
        res += base_sql.format(do_)
    ##print("res:{}".format(res))
    return res


class StockAnnouncementApiView(APIView):
    def post(self, request):
        """ 必须使用code进行查询 使用全路径的code{\d6} 进行匹配"""
        ##print("input : {}".format(request.data))
        code = wrapper_2_list(request.data.get("kw",[]))
        kong_list = wrapper_2_list(request.data.get("kong",[]))
        duo_list = wrapper_2_list(request.data.get("duo",[]))
        if len(code) > 6:
            code = code[:6]
        session = HDY_DBSession_mysql()
        res = {}
        try:
            if code and code[0] and re.match("\d{6}", code[0]):
                code = code[0]
                paginator = paginator_sql(all = True, **request.query_params)
                like_sql = generate_mutil_or_like(" CONCAT(SA.code) ", code, need_where=True)
                # like_sql = generate_mutil_or_like(" CONCAT(SA.code) ", code, single=True, need_where=True)

                kong_sql = generate_mutil_case_sql(" WHEN SA.title like '%{0}%' then '{0}' ", kong_list)
                duo_sql = generate_mutil_case_sql(" WHEN SA.title like '%{0}%' then '{0}' ", duo_list)

                rp = session.execute("SELECT SA.date,(case when goodorbad='-1' then '利空'"\
                        " when goodorbad='1' then '利多' {} {} "\
                        " else '未分类' end) as goodorbad, SA.title ,SA.url  FROM {}.{} AS SA ".format(kong_sql, duo_sql,StockAnnounceDB, LiduoLikongForCodeTablePrefix + code) + like_sql  + " ORDER BY SA.date DESC " + paginator['sql'])
                res['data'] = parse_rp_2_dicts(rp)

        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()


class FinancialApiView(APIView):
    def post(self, request):
        """ 必须使用code进行查询 使用全路径的code{\d6} 进行匹配"""
        ##print("input : {}".format(request.data))
        code = wrapper_2_list(request.data.get("kw",[]))

        session = HDY_DBSession_mysql()
        res = {}
        try:
            if code:
                if len(code) > 6:
                    pass
                code = code[:6]
                res_obj = {}
                # 需要查出本年度和上年度的
                paginator = paginator_sql(all = True, **request.query_params)
                like_sql = generate_mutil_or_like("CONCAT(SA.code)", code, need_where=True)
                query_two_dates_sql = "SELECT a.goodwill, a.total_assets, a.date, a.total_liab, b.n_income, b.n_income_attr_p, b.sell_exp, b.admin_exp, b.fin_exp from "+ FinancialDB+".balancesheet as a INNER JOIN  "+FinancialDB+".income as b where a.code = b.code and a.date = b.date and a.code = :code order by a.date desc limit 2;"
                rp = session.execute(query_two_dates_sql, {"code":code})
                objs = parse_rp_2_dicts(rp)
                if len(objs) < 1 :
                    raise  Exception("缺少该股票的财务数据")
                res_obj = objs[0]
                res_obj['n_income_2'] = objs[1]['n_income']
                if 'date' in res_obj and len(str(res_obj['date'])) == 8:
                    date_ = str(res_obj['date'])
                    date_ = str(int(date_[:4]) -1 ) + date_[4:]
                    rp = parse_rp_2_dicts(session.execute("SELECT sell_exp, admin_exp, fin_exp from "+FinancialDB+".income where date = :date and code = :code;", {'date':date_, 'code': code}))
                    if rp:
                        rp = rp[0]
                        res_obj['pre_sell_exp'] = rp['sell_exp']
                        res_obj['pre_admin_exp'] = rp['admin_exp']
                        res_obj['pre_fin_exp'] = rp['fin_exp']

                res['data'] = [res_obj,]
                        # sell_exp, admin_exp, fin_exp
                # rp = session.execute("SELECT SA.* FROM {}.{} AS SA ".format(StockAnnounceDB, LiduoLikongForCodeTablePrefix + code) + like_sql  + " ORDER BY SA.date DESC " + paginator['sql'])
                # res['data'] = parse_rp_2_dicts(rp)

        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            session.close()

class POSTApiView(APIView):
    def post(self, request):
        """ 必须使用code进行查询 使用全路径的code{\d6} 进行匹配"""
        res = {}
        try:
            res['data'] = request.data
            print("input:{}".format(request.data))
        except Exception as e:
            log.exception(e)
            return JsonResponse(generate_message_dict_4_fail(status.HTTP_500_INTERNAL_SERVER_ERROR
                                                             , e.args))
        else:
            return JsonResponse(wrapper_res_dict(res, False))
        finally:
            pass